package org.kernelab.basis.apps;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.OutputStreamWriter;
import java.io.StringReader;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.kernelab.basis.Filter;
import org.kernelab.basis.Tools;
import org.kernelab.basis.gui.JTextAreaOutputStream;
import org.kernelab.basis.util.CharacterFilter;

public class AppletCharacterFilter extends JApplet
{

	/**
	 * 
	 */
	private static final long	serialVersionUID	= 6933334076261194973L;

	public static String[]		FILTER_SELECTOR		= new String[] { "回车", "制表符" };

	public static char[]		FILTER_CHARACTER	= new char[] { '\n', '\t' };

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		new AppCharacterFilter();
	}

	private CharacterFilter			filter;

	private JTextArea				sourceTextArea, resultTextArea;

	private JTextAreaOutputStream	resultOutputStream;

	private JScrollPane				sourcePane, resultPane;

	private JButton					filterButton;

	private JComboBox				filterSelector;

	public AppletCharacterFilter()
	{
		super();
		Tools.configLookAndFeel();
		this.config();
		this.arrange();
	}

	private void arrange()
	{
		final GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.insets = new Insets(1, 1, 1, 1);
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;

		JPanel sourcePanel = new JPanel(new GridBagLayout());
		sourcePanel.add(this.getSourcePane(), gbc);

		JPanel filterPanel = new JPanel(new GridBagLayout());

		filterPanel.add(this.getFilterButton(), gbc);
		gbc.gridx++;
		gbc.weightx = 0.4;
		filterPanel.add(this.getFilterSelector(), gbc);

		gbc.gridx--;
		gbc.weightx = 1.0;
		JPanel resultPanel = new JPanel(new GridBagLayout());
		resultPanel.add(this.getResultPane(), gbc);

		this.setLayout(new GridBagLayout());

		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		this.add(sourcePanel, gbc);

		gbc.gridy++;
		gbc.weighty = 0.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		this.add(filterPanel, gbc);

		gbc.gridy++;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weighty = 1.0;
		this.add(resultPanel, gbc);

		this.setVisible(true);
	}

	private void config()
	{
		this.setFilter(new CharacterFilter());

		this.setFilter(FILTER_CHARACTER[0]);

		this.setSourceTextArea(new JTextArea());

		this.setSourcePane(new JScrollPane(this.getSourceTextArea()));

		this.getSourcePane().setHorizontalScrollBarPolicy(
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		this.getSourcePane().setVerticalScrollBarPolicy(
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

		this.getSourcePane().setPreferredSize(new Dimension(500, 300));

		this.setResultTextArea(new JTextArea());

		this.setResultPane(new JScrollPane(this.getResultTextArea()));

		this.getResultTextArea().setLineWrap(true);

		this.getResultPane().setHorizontalScrollBarPolicy(
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		this.getResultPane().setVerticalScrollBarPolicy(
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

		this.getResultPane().setPreferredSize(new Dimension(500, 300));

		this.setResultOutputStream(new JTextAreaOutputStream(getResultTextArea(),
				JTextAreaOutputStream.APPEND));

		this.getFilter().setWriter(new OutputStreamWriter(this.getResultOutputStream()));

		this.setFilterSelector(new JComboBox());

		for (String item : FILTER_SELECTOR) {
			this.getFilterSelector().addItem(item);
		}

		this.setFilterButton(new JButton("Filter"));

		this.getFilterButton().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e)
			{
				setFilter(FILTER_CHARACTER[getFilterSelector().getSelectedIndex()]);
				getResultTextArea().setText("");
				getFilter().setReader(new StringReader(getSourceTextArea().getText()));
				Thread thread = new Thread(getFilter());
				thread.start();
			}

		});

	}

	public CharacterFilter getFilter()
	{
		return filter;
	}

	public JButton getFilterButton()
	{
		return filterButton;
	}

	public JComboBox getFilterSelector()
	{
		return filterSelector;
	}

	private JTextAreaOutputStream getResultOutputStream()
	{
		return resultOutputStream;
	}

	public JScrollPane getResultPane()
	{
		return resultPane;
	}

	public JTextArea getResultTextArea()
	{
		return resultTextArea;
	}

	public JScrollPane getSourcePane()
	{
		return sourcePane;
	}

	public JTextArea getSourceTextArea()
	{
		return sourceTextArea;
	}

	private void setFilter(final char filter)
	{
		this.getFilter().getFilters().clear();
		this.getFilter().getFilters().add(new Filter<Character>() {

			@Override
			public boolean filter(Character e)
			{
				return e == filter;
			}

		});
	}

	private void setFilter(CharacterFilter filter)
	{
		this.filter = filter;
	}

	private void setFilterButton(JButton filterButton)
	{
		this.filterButton = filterButton;
	}

	private void setFilterSelector(JComboBox filterSelector)
	{
		this.filterSelector = filterSelector;
	}

	private void setResultOutputStream(JTextAreaOutputStream resultOutputStream)
	{
		this.resultOutputStream = resultOutputStream;
	}

	private void setResultPane(JScrollPane resultPane)
	{
		this.resultPane = resultPane;
	}

	private void setResultTextArea(JTextArea resultTextArea)
	{
		this.resultTextArea = resultTextArea;
	}

	private void setSourcePane(JScrollPane sourcePane)
	{
		this.sourcePane = sourcePane;
	}

	private void setSourceTextArea(JTextArea sourceTextArea)
	{
		this.sourceTextArea = sourceTextArea;
	}

}
